// Copyright (c) Microsoft Corporation. All rights reserved.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;

using Microsoft.TeamFoundation.Migration.Toolkit.Wit;

namespace Microsoft.TeamFoundation.Migration.Toolkit.Linking
{
    /// <summary>
    /// Artifact handler for latest version of a VC file.
    /// </summary>
    public class TfsLatestFileHandler: IArtifactHandler
    {
        private ILinkEngine m_engine;                       // Linking engine

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="engine">Linking engine</param>
        public TfsLatestFileHandler(
            ILinkEngine engine)
        {
            if (engine == null)
            {
                throw new ArgumentNullException("engine");
            }
            m_engine = engine;
        }

        #region IArtifactHandler Members

        public bool TryFindReflection(
            SystemType sourceSystem, 
            string sourceUri, 
            out string targetId)
        {
            if (string.IsNullOrEmpty(sourceUri))
            {
                throw new ArgumentNullException("sourceUri");
            }

            targetId = null;
            if (IsMyUri(sourceUri))
            {
                if (! (m_engine.VersionControlSession.Source is IVersionControlLinkableEndPoint))
                {
                    TraceManager.TraceWarning("The source system doesn't implement interface IVersionControlLinkableEndPoint. Get latest file is not supported");
                    return false;
                }

                IVersionControlLinkableEndPoint sourcePoint;
                IVersionControlLinkableEndPoint targetPoint;
                bool useSource = (sourceSystem == SystemType.Other);
                if (useSource)
                {
                    targetPoint = m_engine.VersionControlSession.Target;
                    sourcePoint = (IVersionControlLinkableEndPoint)m_engine.VersionControlSession.Source;
                }
                else
                {
                    targetPoint = (IVersionControlLinkableEndPoint)m_engine.VersionControlSession.Source;
                    sourcePoint = m_engine.VersionControlSession.Target;
                }

                string sourcePath = sourcePoint.GetPathFromLatestItemVersion(sourceUri);
                if (!string.IsNullOrEmpty(sourcePath))
                {
                    string linkedPath = sourcePoint.FindMappedPath(sourcePath, m_engine.VersionControlSession, useSource);
                    if (!string.IsNullOrEmpty(linkedPath))
                    {
                        targetId = targetPoint.GetLatestItemIdFromPath(linkedPath);
                    }
                }
                return true;
            }
            return false;
        }

        public bool TryTranslateUri(string uri, out string id)
        {
            if (string.IsNullOrEmpty(uri))
            {
                throw new ArgumentNullException("uri");
            }

            if (IsMyUri(uri))
            {
                id = uri.Substring(LinkingConstants.VcLatestFilePrefix.Length);
                return true;
            }
            else
            {
                id = null;
            }
            return false;
        }

        public string CreateUri(string id)
        {
            return LinkingConstants.VcLatestFilePrefix + id;
        }

        #endregion

        /// <summary>
        /// Checks whether URI points to a known artifact.
        /// </summary>
        /// <param name="uri">Artifact's URI</param>
        /// <returns>True if URI belongs to a known artifact</returns>
        internal static bool IsMyUri(
            string uri)
        {
            return uri.StartsWith(LinkingConstants.VcLatestFilePrefix, StringComparison.InvariantCulture);
        }
    }
}
